package com.moliku.insurance.process.service.impl;

import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.moliku.insurance.common.constant.CompanyEnum;
import com.moliku.insurance.common.constant.InsureStatusEnum;
import com.moliku.insurance.common.constant.OrderEnum;
import com.moliku.insurance.common.constant.PolicyConfigKeyEnum;
import com.moliku.insurance.common.response.CommonInsureResult;
import com.moliku.insurance.common.util.XMLUtil;
import com.moliku.insurance.model.dto.CancelInsureDTO;
import com.moliku.insurance.model.dto.DownloadInsureDTO;
import com.moliku.insurance.model.dto.insure.InsureDTO;
import com.moliku.insurance.model.dto.insure.InsuredInfoDTO;
import com.moliku.insurance.model.entity.Order;
import com.moliku.insurance.model.entity.OrderDetail;
import com.moliku.insurance.model.entity.allianz.*;
import com.moliku.insurance.process.mapper.BaseOrderMapper;
import com.moliku.insurance.process.service.ConfigService;
import com.moliku.insurance.process.strategy.PolicyStrategy;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.config.AuthSchemes;
import org.apache.http.client.config.CookieSpecs;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.config.Registry;
import org.apache.http.config.RegistryBuilder;
import org.apache.http.conn.socket.ConnectionSocketFactory;
import org.apache.http.conn.socket.PlainConnectionSocketFactory;
import org.apache.http.conn.ssl.NoopHostnameVerifier;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.util.EntityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.X509Certificate;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * 京东安联
 *
 * @author Mr.Liu
 * @since 2021/2/5
 */
@Slf4j
@AllArgsConstructor
@Service("AllianzService")
public class AllianzServiceImpl implements PolicyStrategy {
    /**
     * 安联通用请求地址
     */
//    private static final String ALLIANZ_COMMON_INTERFACE_URL = "https://test.allianz.cn/IG_ePolicy/OTI-azcn-policy";
    /**
     * 编码
     */
    private static final String ENCODEING = "UTF-8";

    /**
     * 响应成功的状态码
     */
    private static final String RESPONSE_SUCCESS_CODE = "0000";

    /**
     * 重复退保的状态码
     */
    private static final String REPEAT_SUCCESS_CODE = "1008";
    /**
     * 重复退保的状态码
     */
    private static final String REPEAT_CANCEL_SUCCESS_CODE = "1110";

    @Autowired
    private BaseOrderMapper baseOrderMapper;
    @Autowired
    private ConfigService configService;

    @Override
    public CommonInsureResult submitPolicy(InsureDTO request) {
        //旅意
        if ("ALCDTP1".equals(request.getOrder().getProductCode())) {
            return submitPolicyTourism(request);
        }
        //百万医疗
        return submitPolicyMedical(request);
    }


    @Override
    public CommonInsureResult cancelPolicy(CancelInsureDTO request) {
        try {
            //保单主体信息
            AllianzQuitPolicy allianzQuitPolicy = new AllianzQuitPolicy();
            allianzQuitPolicy.setPolicyRef(request.getPolicyNo());
//            allianzQuitPolicy.setAgencyPolicyRef(request.getSerialNo());

            //退保信息
            CancellationInfo cancellationInfo = new CancellationInfo();
            //退保原因
//            cancellationInfo.setReasonRemark(request.getApplicationReason());
            cancellationInfo.setReasonRemark("用户改期");

            AllianzQuitBody allianzQuitBody = new AllianzQuitBody();
            allianzQuitBody.setPolicy(allianzQuitPolicy);
            allianzQuitBody.setCancellationInfo(cancellationInfo);

            AllianzQuitRequest allianzQuitRequest = new AllianzQuitRequest();
            //查询账号密码
            String username = configService.getConfigValue(CompanyEnum.ALLIANZ, PolicyConfigKeyEnum.USERNAME);
            String password = configService.getConfigValue(CompanyEnum.ALLIANZ, PolicyConfigKeyEnum.PASSWORD);
            allianzQuitRequest.setHead(getHead("0004", username, password));
            allianzQuitRequest.setBody(allianzQuitBody);

            String strXml = XMLUtil.convertToXml(allianzQuitRequest);
            log.info("退保请求xml---{}", strXml);
            //发起请求
            String result = sentHttpPostRequest(strXml);
            log.info("退保响应--{}", result);
            //判断响应格式是否是XML类型
            if (!XMLUtil.isXmlDocument(result)) {
                return CommonInsureResult.cancelPolicyFail("京东安联退保响应异常！");
            }
            //xml转json
            JSONObject jsonObject = JSONUtil.xmlToJson(result);
            log.info("xml转json--{}", jsonObject.toString());
            Order orderInfo = baseOrderMapper.selectByPolicyNo(request.getPolicyNo());
            OrderDetail orderDetail = baseOrderMapper.selectDeatailByOrderId(orderInfo.getId());
            orderDetail.setCancelPolicyRsp(jsonObject.toString());
            baseOrderMapper.updateOrderDeatailByOrderId(orderDetail);
            String head = JSONUtil.parseObj(jsonObject.get("Packet")).isNull("Head") ? "" : JSONUtil.parseObj(jsonObject.get("Packet")).get("Head").toString();
            //响应内容不空
            if (!StringUtils.isBlank(head)) {
                String statusCode = JSONUtil.parseObj(head).get("ErrorCode").toString();
                //接口响应0000代表成功
                if (RESPONSE_SUCCESS_CODE.equals(statusCode)) {
                    //更改订单状态
                    orderInfo.setStatus(OrderEnum.CANCEL.getValue());
                    baseOrderMapper.updateById(orderInfo);
                    return CommonInsureResult.cancelPolicySuccess();
                } else if (REPEAT_SUCCESS_CODE.equals(statusCode) || REPEAT_CANCEL_SUCCESS_CODE.equals(statusCode)) {
                    return CommonInsureResult.cancelPolicyFail(InsureStatusEnum.CANCEL_INSURE_FAIL_5201);
                } else {
                    String errorMessage = JSONUtil.parseObj(head).get("ErrorMessage").toString();
                    return CommonInsureResult.cancelPolicyFail(errorMessage);
                }
            } else {
                return CommonInsureResult.cancelPolicyFail("京东安联响应内容为空！");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return CommonInsureResult.cancelPolicyFail();
    }

    @Override
    public CommonInsureResult downloadPolicy(DownloadInsureDTO downloadInsure) {
        try {
            //保单主体
            AllianzDownloadPolicy allianzDownloadPolicy = new AllianzDownloadPolicy();
            allianzDownloadPolicy.setPolicyRef(downloadInsure.getPolicyNo());
            //保单模板 F01-正常打印模板 F02-使用套打模板
//            allianzDownloadPolicy.setFormat(downloadInsure.getFormat());
            allianzDownloadPolicy.setFormat("F01");

            AllianzDownloadBody allianzDownloadBody = new AllianzDownloadBody();
            allianzDownloadBody.setPolicy(allianzDownloadPolicy);

            AllianzDownloadRequest allianzDownloadRequest = new AllianzDownloadRequest();
            //查询账号密码
            String username = configService.getConfigValue(CompanyEnum.ALLIANZ, PolicyConfigKeyEnum.USERNAME);
            String password = configService.getConfigValue(CompanyEnum.ALLIANZ, PolicyConfigKeyEnum.PASSWORD);
            allianzDownloadRequest.setHead(getHead("0006", username, password));
            allianzDownloadRequest.setBody(allianzDownloadBody);

            String strXml = XMLUtil.convertToXml(allianzDownloadRequest);
            log.info("下载保单请求xml---{}", strXml);
            //发起请求
            byte[] result = sentHttpPostRequestDownload(strXml);
            downloadFile(result);
            if (null == result || result.length == 0) {
                return CommonInsureResult.downloadPolicyFail();
            }
            return CommonInsureResult.downloadPolicySuccess(result);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return CommonInsureResult.downloadPolicyFail();
    }


    /**
     * @Description: 旅游意外险
     * @Author: yws
     * @Date: 2021/3/12 15:03
     */
    private CommonInsureResult submitPolicyTourism(InsureDTO request) {
        try {
            //保单主体信息
            AllianzPolicy allianzPolicy = new AllianzPolicy();
            allianzPolicy.setAgencyPolicyRef(request.getOrder().getSerialNumber());
            //安联保险计划代码
            allianzPolicy.setPlanCode(request.getOrder().getProductCode());
            SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
            allianzPolicy.setIssueDate(sdf.format(new Date()));
            allianzPolicy.setEffectiveDate(request.getOrder().getStartTime());
            allianzPolicy.setExpireDate(request.getOrder().getEndTime());
            //被保险人总个数
//            allianzPolicy.setGroupSize(request.getOrder().getCoverageCopies());

            //渠道信息
            AllianzAgency allianzAgency = new AllianzAgency();
            allianzAgency.setAgencyCode("AC600002");

            //投保人信息
            AllianzPolicyHolder allianzPolicyHolder = new AllianzPolicyHolder();
            //投保人类型
            allianzPolicyHolder.setPolicyHolderType("I");
            allianzPolicyHolder.setPolicyHolderName(request.getPolicyHolder().getcName());
            allianzPolicyHolder.setPHIdType(getCardType(request.getPolicyHolder().getCardType()));
            allianzPolicyHolder.setPHIdNumber(request.getPolicyHolder().getCardNo());
            allianzPolicyHolder.setPHBirthDate(request.getPolicyHolder().getBirthDay().replaceAll("-", ""));
            allianzPolicyHolder.setPHTelephone(request.getPolicyHolder().getMobile());
            allianzPolicyHolder.setPHEmail(request.getPolicyHolder().getEmail());
            //是否邮寄发票，默认不需要
            allianzPolicyHolder.setReqMail("0");
            //是否打印发票，默认不需要
            allianzPolicyHolder.setReqFaPiao("0");

            List<AllianzInsuredList> allianzInsuredLists = new ArrayList<>();
            for (InsuredInfoDTO insure : request.getInsureds()) {
                //被保人信息
                AllianzInsured allianzInsured = new AllianzInsured();
                //被保险人唯一Id，用来确认该保单下被保险人的唯一性
                allianzInsured.setInsuredId(insure.getCardNo());
                allianzInsured.setInsuredType(getInsuredType(request.getOrder().getStartTime(), insure.getBirthDay()));
                allianzInsured.setInsuredName(insure.getCName());
                allianzInsured.setIdType(getCardType(insure.getCardType()));
                allianzInsured.setIdNumber(insure.getCardNo());
                allianzInsured.setBirthDate(insure.getBirthDay().replaceAll("-", ""));
                allianzInsured.setMobile(insure.getMobile());
                allianzInsured.setEmail(insure.getEmail());
                allianzInsured.setGender(getGender(insure.getSex()));
                //受益类型
                allianzInsured.setBeneficialType("1");
                AllianzInsuredList allianzInsuredlist = new AllianzInsuredList();
                allianzInsuredlist.setInsured(allianzInsured);
                allianzInsuredLists.add(allianzInsuredlist);
            }

            AllianzBody allianzBody = new AllianzBody();
            allianzBody.setAgency(allianzAgency);
            allianzBody.setPolicy(allianzPolicy);
            allianzBody.setPolicyHolder(allianzPolicyHolder);
            allianzBody.setInsuredList(allianzInsuredLists);

            AllianzRequest allianzRequest = new AllianzRequest();
            //查询账号密码
            String username = configService.getConfigValue(CompanyEnum.ALLIANZ, PolicyConfigKeyEnum.USERNAME);
            String password = configService.getConfigValue(CompanyEnum.ALLIANZ, PolicyConfigKeyEnum.PASSWORD);
            allianzRequest.setHead(getHead("0002", username, password));
            allianzRequest.setBody(allianzBody);

            String strXml = XMLUtil.convertToXml(allianzRequest);
            log.info("投保请求xml---{}", strXml);
            //发起请求
            String result = sentHttpPostRequest(strXml);
            log.info("投保响应--{}", result);
            //判断响应格式是否是XML类型
            if (!XMLUtil.isXmlDocument(result)) {
                return CommonInsureResult.submitPolicyFail("京东安联响应内容异常！");
            }
            //xml转json
            JSONObject jsonObject = JSONUtil.xmlToJson(result);
            log.info("xml转json--{}", jsonObject.toString());
            Order order = baseOrderMapper.selectById(request.getLocalOrderId());
            OrderDetail orderDetaill = baseOrderMapper.selectDeatailByOrderId(order.getId());
            orderDetaill.setCancelPolicyRsp(jsonObject.toString());
            baseOrderMapper.updateOrderDeatailByOrderId(orderDetaill);


            String head = JSONUtil.parseObj(jsonObject.get("Packet")).isNull("Head") ? "" : JSONUtil.parseObj(jsonObject.get("Packet")).get("Head").toString();
            String body = JSONUtil.parseObj(jsonObject.get("Packet")).isNull("Body") ? "" : JSONUtil.parseObj(jsonObject.get("Packet")).get("Body").toString();
            Map<String, String> map = new HashMap<>(2);
            //响应内容都不空
            String policyNo = "";
            if (!StringUtils.isBlank(head) && !StringUtils.isBlank(body)) {
                String statusCode = JSONUtil.parseObj(head).get("ErrorCode").toString();
                //接口响应0000代表成功
                if (RESPONSE_SUCCESS_CODE.equals(statusCode)) {
                    //获取保单号
                    policyNo = JSONUtil.parseObj(body).get("PolicyRef").toString();
                    String agencyPolicyRef = JSONUtil.parseObj(body).get("AgencyPolicyRef").toString();
                    map.put("PolicyRef", policyNo);
                    map.put("AgencyPolicyRef", agencyPolicyRef);
                    //获取保单状态
                    order.setPolicyNo(policyNo);
                    order.setStatus(OrderEnum.CLOSED_NO_REFUND.getValue());
                    baseOrderMapper.updateById(order);
                } else {
                    String errorMessage = JSONUtil.parseObj(head).get("ErrorMessage").toString();
                    return CommonInsureResult.submitPolicyFail("投保失败！" + errorMessage);
                }
            } else {
                String errorMessage = JSONUtil.parseObj(head).get("ErrorMessage").toString();
                return CommonInsureResult.submitPolicyFail("投保失败！" + errorMessage);
            }
            return CommonInsureResult.submitPolicySuccess(policyNo);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return CommonInsureResult.submitPolicyFail();
    }


    /**
     * @Description: 百万医疗
     * @Author: yws
     * @Date: 2021/3/12 15:03
     */
    private CommonInsureResult submitPolicyMedical(InsureDTO request) {
        try {
            //保单主体信息
            AllianzPolicy allianzPolicy = new AllianzPolicy();
            allianzPolicy.setAgencyPolicyRef(request.getOrder().getSerialNumber());
            //保费计算方式，同计划类型
            allianzPolicy.setPremiumCalType("3");
            allianzPolicy.setIsOptional("1");
            SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
            allianzPolicy.setIssueDate(sdf.format(new Date()));
            allianzPolicy.setEffectiveDate(request.getOrder().getStartTime());
            allianzPolicy.setExpireDate(request.getOrder().getEndTime());
            //被保险人总个数
//            allianzPolicy.setGroupSize(request.getOrder().getCoverageCopies());

            //渠道信息
            AllianzAgency allianzAgency = new AllianzAgency();
            allianzAgency.setAgencyCode("AC600002");

            //投保人信息
            AllianzPolicyHolder allianzPolicyHolder = new AllianzPolicyHolder();
            //投保人类型
            allianzPolicyHolder.setPolicyHolderType("I");
            allianzPolicyHolder.setPolicyHolderName(request.getPolicyHolder().getcName());
            allianzPolicyHolder.setPHIdType(getCardType(request.getPolicyHolder().getCardType()));
            allianzPolicyHolder.setPHIdNumber(request.getPolicyHolder().getCardNo());
            allianzPolicyHolder.setPHBirthDate(request.getPolicyHolder().getBirthDay().replaceAll("-", ""));
            allianzPolicyHolder.setPHTelephone(request.getPolicyHolder().getMobile());
            allianzPolicyHolder.setPHEmail(request.getPolicyHolder().getEmail());
            //是否邮寄发票，默认不需要
            allianzPolicyHolder.setReqMail("0");
            //是否打印发票，默认不需要
            allianzPolicyHolder.setReqFaPiao("0");


            List<AllianzInsuredMedicalList> allianzInsuredMedicalLists = new ArrayList<>();
            for (InsuredInfoDTO insure : request.getInsureds()) {
                //被保人信息
                AllianzInsuredMedical allianzInsuredMedical = new AllianzInsuredMedical();
                //被保险人唯一Id，用来确认该保单下被保险人的唯一性
                allianzInsuredMedical.setInsuredId(insure.getCardNo());
                allianzInsuredMedical.setInsuredType(getInsuredType(request.getOrder().getStartTime(), insure.getBirthDay()));
                allianzInsuredMedical.setInsuredName(insure.getCName());
                allianzInsuredMedical.setIdType(getCardType(insure.getCardType()));
                allianzInsuredMedical.setIdNumber(insure.getCardNo());
                allianzInsuredMedical.setBirthDate(insure.getBirthDay().replaceAll("-", ""));
                allianzInsuredMedical.setMobile(insure.getMobile());
                allianzInsuredMedical.setEmail(insure.getEmail());
                allianzInsuredMedical.setGender(getGender(insure.getSex()));
                //受益类型
                allianzInsuredMedical.setBeneficialType("1");
                //被保险人职业代码
                allianzInsuredMedical.setOccupationCode("J02012");
                //与投保人关系
                allianzInsuredMedical.setPolicyholderInsuredRelation("02");
                //是否有社保
                allianzInsuredMedical.setSocialSecurityFlag("Y");
                allianzInsuredMedical.setPlanCode("ZAAMIPHB(2021)F");
                AllianzInsuredMedicalList allianzInsuredMedicalList = new AllianzInsuredMedicalList();
                allianzInsuredMedicalList.setInsured(allianzInsuredMedical);
                allianzInsuredMedicalLists.add(allianzInsuredMedicalList);
            }
            //body
            AllianzBodyMedical allianzBodyMedical = new AllianzBodyMedical();
            allianzBodyMedical.setAgency(allianzAgency);
            allianzBodyMedical.setPolicy(allianzPolicy);
            allianzBodyMedical.setPolicyHolder(allianzPolicyHolder);
            allianzBodyMedical.setInsuredList(allianzInsuredMedicalLists);

            //请求
            AllianzRequestMedical allianzRequest = new AllianzRequestMedical();
            //查询账号密码
            String username = configService.getConfigValue(CompanyEnum.ALLIANZ, PolicyConfigKeyEnum.USERNAME);
            String password = configService.getConfigValue(CompanyEnum.ALLIANZ, PolicyConfigKeyEnum.PASSWORD);
            allianzRequest.setHead(getHead("0002", username, password));
            allianzRequest.setBody(allianzBodyMedical);

            String strXml = XMLUtil.convertToXml(allianzRequest);
            log.info("投保请求xml---{}", strXml);
            //发起请求
            String result = sentHttpPostRequest(strXml);
            log.info("投保响应--{}", result);
            //判断响应格式是否是XML类型
            if (!XMLUtil.isXmlDocument(result)) {
                return CommonInsureResult.submitPolicyFail("京东安联响应内容异常！");
            }
            //xml转json
            JSONObject jsonObject = JSONUtil.xmlToJson(result);
            log.info("xml转json--{}", jsonObject.toString());
            Order order = baseOrderMapper.selectById(request.getLocalOrderId());
            OrderDetail orderDetaill = baseOrderMapper.selectDeatailByOrderId(order.getId());
            orderDetaill.setCancelPolicyRsp(jsonObject.toString());
            baseOrderMapper.updateOrderDeatailByOrderId(orderDetaill);
            String head = JSONUtil.parseObj(jsonObject.get("Packet")).isNull("Head") ? "" : JSONUtil.parseObj(jsonObject.get("Packet")).get("Head").toString();
            String body = JSONUtil.parseObj(jsonObject.get("Packet")).isNull("Body") ? "" : JSONUtil.parseObj(jsonObject.get("Packet")).get("Body").toString();
            Map<String, String> map = new HashMap<>(2);
            //响应内容都不空
            String policyNo = "";
            if (!StringUtils.isBlank(head) && !StringUtils.isBlank(body)) {
                String statusCode = JSONUtil.parseObj(head).get("ErrorCode").toString();
                //接口响应0000代表成功
                if (RESPONSE_SUCCESS_CODE.equals(statusCode)) {
                    //获取保单号
                    policyNo = JSONUtil.parseObj(body).get("PolicyRef").toString();
                    String agencyPolicyRef = JSONUtil.parseObj(body).get("AgencyPolicyRef").toString();
                    map.put("PolicyRef", policyNo);
                    map.put("AgencyPolicyRef", agencyPolicyRef);
                    //获取保单状态
                    order.setPolicyNo(policyNo);
                    order.setStatus(OrderEnum.CLOSED_NO_REFUND.getValue());
                    baseOrderMapper.updateById(order);
                } else {
                    String errorMessage = JSONUtil.parseObj(head).get("ErrorMessage").toString();
                    return CommonInsureResult.submitPolicyFail("投保失败：" + errorMessage);
                }
            } else {
                String errorMessage = JSONUtil.parseObj(head).get("ErrorMessage").toString();
                return CommonInsureResult.submitPolicyFail("投保失败：" + errorMessage);
            }
            return CommonInsureResult.submitPolicySuccess(policyNo);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return CommonInsureResult.submitPolicyFail();
    }


    /**
     * 公共方法:HttpClient 如何忽略证书验证访问https
     * 将过时方法修改了
     *
     * @return HttpClient
     */
    private static HttpClient sslClient() {
        try {
            // 在调用SSL之前需要重写验证方法，取消检测SSL
            X509TrustManager trustManager = new X509TrustManager() {
                @Override
                public X509Certificate[] getAcceptedIssuers() {
                    return null;
                }

                @Override
                public void checkClientTrusted(X509Certificate[] xcs, String str) {
                }

                @Override
                public void checkServerTrusted(X509Certificate[] xcs, String str) {
                }
            };
            SSLContext ctx = SSLContext.getInstance(SSLConnectionSocketFactory.TLS);
            ctx.init(null, new TrustManager[]{trustManager}, null);
            SSLConnectionSocketFactory socketFactory = new SSLConnectionSocketFactory(ctx, NoopHostnameVerifier.INSTANCE);
            // 创建Registry
            RequestConfig requestConfig = RequestConfig.custom().setCookieSpec(CookieSpecs.STANDARD_STRICT)
                    .setExpectContinueEnabled(Boolean.TRUE).setTargetPreferredAuthSchemes(Arrays.asList(AuthSchemes.NTLM, AuthSchemes.DIGEST))
                    .setProxyPreferredAuthSchemes(Collections.singletonList(AuthSchemes.BASIC)).build();
            Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory>create()
                    .register("http", PlainConnectionSocketFactory.INSTANCE)
                    .register("https", socketFactory).build();
            // 创建ConnectionManager，添加Connection配置信息
            PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager(socketFactoryRegistry);
            return HttpClients.custom().setConnectionManager(connectionManager)
                    .setDefaultRequestConfig(requestConfig).build();
        } catch (KeyManagementException | NoSuchAlgorithmException ex) {
            throw new RuntimeException(ex);
        }
    }

    /**
     * @Description: 封装请求投保退保 文档中给的示例 将过时方法修改了
     * @Param: requestMsg 请求报文
     * @Author: yws
     * @Date: 2021/3/10 10:48
     */
    public String sentHttpPostRequest(String requestMsg) throws IOException {
        String commonUrl = configService.getConfigValue(CompanyEnum.ALLIANZ, PolicyConfigKeyEnum.SUBMIT_POLICY_URL);
        //去掉检测Https
        HttpClient httpclient = sslClient();
        //设置请求地址
        HttpPost httpPost = new HttpPost(commonUrl);
        //设置请求内容和编码
        StringEntity urlEntity = new StringEntity(requestMsg, ENCODEING);
        //设置请求体
        httpPost.setEntity(urlEntity);
        //发起请求
        HttpResponse response = httpclient.execute(httpPost);
        //处理响应内容
        HttpEntity entity = response.getEntity();
        String result = null;
        if (entity != null) {
            result = EntityUtils.toString(entity);
        }
        return result;
    }

    /**
     * @Description: 封装下载请求 文档中给的示例 将过时方法修改了
     * @Param: requestMsg 请求报文
     * @Author: yws
     * @Date: 2021/3/10 10:48
     */
    public byte[] sentHttpPostRequestDownload(String requestMsg) throws IOException {
        String commonUrl = configService.getConfigValue(CompanyEnum.ALLIANZ, PolicyConfigKeyEnum.SUBMIT_POLICY_URL);
        //去掉检测Https
        HttpClient httpclient = sslClient();
        //设置请求地址
        HttpPost httpPost = new HttpPost(commonUrl);
        //设置请求内容和编码
        StringEntity urlEntity = new StringEntity(requestMsg, ENCODEING);
        //设置请求体
        httpPost.setEntity(urlEntity);
        //发起请求
        HttpResponse response = httpclient.execute(httpPost);
        //处理响应内容
        HttpEntity entity = response.getEntity();
        byte[] result = null;
        if (entity != null) {
            result = EntityUtils.toByteArray(entity);
        }
        return result;
    }

    /**
     * @Description: 请求头信息
     * @Param: requestType 请求的接口类型代码0002 投保0004 退保0006 下载保单
     * @Param: user 用户
     * @Param: password 用户密码
     * @Return: AllianzHead 请求头信息
     * @Author: yws
     * @Date: 2021/3/9 15:26
     */
    private static AllianzHead getHead(String requestType, String user, String password) {
        AllianzHead allianzHead = new AllianzHead();
        allianzHead.setRequestType(requestType);
        allianzHead.setUser(user);
        allianzHead.setPassword(password);
        return allianzHead;
    }

    /**
     * @Description: 返回性别
     * @Author: yws
     * @Date: 2021/3/10 16:27
     */
    private static String getGender(String gender) {
        switch (gender) {
            case "1":
                //男
                return "M";
            case "0":
                //女
                return "F";
            default:
                return "O";
        }
    }

    /**
     * @Description: 返回身份证类型
     * @Param: cardType
     * @Return: String
     * @Author: yws
     * @Date: 2021/3/6 10:58
     */
    private static String getCardType(String cardType) {
        switch (cardType) {
            //身份证
            case "1":
                return "1";
            //护照
            case "3":
                return "2";
            //出生证
            case "11":
                return "12";
            //台胞证
            case "12":
                return "16";
            //组织结构代码
            case "72":
                return "4";
            //营业执照
            case "70":
                return "6";
            //营业执照
            case "84":
                return "7";
            //其他
            default:
                return "3";
        }
    }

    /**
     * @Description: 返回被保人类型 被保险人类型(年龄=保单生效日期-出生日期)
     * 1-成人（大于等于18周岁，小于66周岁）
     * 2-儿童（小于18周岁）
     * 3-老人（大于等于66周岁）
     * @Author: yws
     * @Date: 2021/3/10 16:27
     */
    private static String getInsuredType(String effectiveDate, String birthDate) throws Exception {
        //1、定义转换格式
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
        SimpleDateFormat formatterBirth = new SimpleDateFormat("yyyyMMdd");
        Date dateBirth = formatterBirth.parse(birthDate);
        SimpleDateFormat formatterEff = new SimpleDateFormat("yyyyMMddHHmmss");
        Date dateEff = formatterEff.parse(effectiveDate);

        Calendar calBegin = Calendar.getInstance();
        Calendar calEnd = Calendar.getInstance();
        calBegin.setTime(formatter.parse(formatter.format(dateBirth)));
        calEnd.setTime(formatter.parse(formatter.format(dateEff)));
        int age = calEnd.get(Calendar.YEAR) - calBegin.get(Calendar.YEAR);
        System.err.println(age);
        if (18 <= age && 66 > age) {
            return "1";
        } else if (18 > age) {
            return "2";
        } else {
            return "3";
        }
    }


    /**
     * @Description: 下载内容到本地为了测试看一下文件
     * @Param: bytes 字节流
     * @Author: yws
     * @Date: 2021/3/8 15:06
     */
    public static void downloadFile(byte[] bytes) throws Exception {
        String fileName = String.valueOf(System.currentTimeMillis() / 1000) + ".pdf";
        File f = new File("D://tmp/" + fileName);
        if (!f.exists()) {
            try {
                f.createNewFile();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        FileOutputStream out = null;
        try {
            out = new FileOutputStream(f);
            out.write(bytes, 0, bytes.length);
            out.flush();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (out != null) {
                try {
                    out.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        log.info("文件下载完毕：{}", f.getPath());
    }
}
